<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta charset="UTF-8" />
<title>Baby Mash</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>

<script type="text/javascript">

(function( $ ) {
    /**
     * Sets the color based on the position of an element.
     * ASSUME ONLY 1 ELEMENT GIVEN
     *
     * width - The width of the document (passed in for performance)
     * height - The height of the document (passed in for performance)
     *
     * Returns - jQuery
     */
    $.fn.setHSL = function(width, height) {
        var hugh = this.offset().left / width * 360;
        var saturation = "100%";
        var lightness = (this.offset().top / height * 100) + "%";
    
        return this.css( { color : "hsl(" + hugh + ", " + saturation + ", " + lightness + ")" } );
    };

    /**
     * Sets the position of the element to the center.
     * ASSUME ONLY 1 ELEMENT GIVEN
     *
     * width - The width of the document (passed in for performance)
     * height - The height of the document (passed in for performance)
     *
     * Returns - jQuery
     */
    $.fn.setPositionCenter = function(width, height) {
        return this.css( {top: ((height / 2) - (this.height() / 2)) + "px", left : (width / 2) - (this.width() / 2) } );
    };

    /**
     * Sets the position of the element to the given location.
     * ASSUME ONLY 1 ELEMENT GIVEN
     *
     * top - The top of the element
     * left - The left of the element
     *
     * Returns - jQuery
     */
    $.fn.setPosition = function(top, left) {
        return this.css( {top: top + "px", left : left + "px" } );
    };

    /**
     * Animate the element to a random position
     * ASSUME ONLY 1 ELEMENT GIVEN
     *
     * width - The width of the document (passed in for performance)
     * height - The height of the document (passed in for performance)
     *
     * Returns - jQuery
     */
    $.fn.animateToRandomPosition = function(width, height) {
        return this
            .animate({
                top  :  (Math.round((height + this.height()) * Math.random()) - this.height()) + "px",
                left : (Math.round((width + this.width()) * Math.random()) - this.width()) + "px",
                opacity : 0
            }, {
                duration: 1000,
                complete : function() {
                    $(this).remove();
                },
                step : function() {
                    $(this).setHSL(width, height);
                }
            });
    };

    /**
     * Animate the element to the bottom of page
     * ASSUME ONLY 1 ELEMENT GIVEN
     *
     * Returns - jQuery
     */
    $.fn.animateToBottom = function(width, height) {
        return this
            .animate({
                top : height
            }, { 
                duration : 1000,
                complete : function() {
                    $(this).remove();
                },
                step : function() {
                    $(this).setHSL(width, height);
                }
            });
    };
})( jQuery )

$(function() {
    var canvas = $("#canvas").eq(0);
    var width = $(document).width();
    var height = $(document).height();

    var goodUnicodeRanges=[ {
        From: 33, To: 126, Description: "Basic Latin" }, {
        From: 384, To: 686, Description: "Latin" }, {
        From: 910, To: 929, Description: "Greek" }, {
        From: 1632, To: 1791, Description: "Arabic" }, {
        From: 1024, To: 1154, Description: "Cyrillic" }, {
        From: 1488, To: 1514, Description: "Hebrew" }, {
        From: 1632, To: 1791, Description: "Aribic" }, {
        From: 2320, To: 2351, Description: "Devanagari" }, {
        From: 4256, To: 4287, Description: "Georgian" }, {
        From: 4352, To: 4600, Description: "Hangul Jamo" }, {
        From: 8704, To: 8959, Description: "Mathematical" }, {
        From: 10224, To: 10239, Description: "Arrows" }, {
        From: 9632, To: 9711, Description: "Geometric shapes"
    }];

    function getRandomSymbol() {
        var range = goodUnicodeRanges[Math.round(Math.random() * (goodUnicodeRanges.length - 1))];
        return String.fromCharCode(Math.round(Math.random() * (range.To - range.From) + range.From)); 
    }

    function addCharacter(y, x) {
        var size = (Math.round(10 * Math.random()) + 1) + "em";

        return $("<div></div>")
            .text(getRandomSymbol())
            .css( { "font-size" : size } )
            .appendTo(canvas);
    }

    $(document)
    .mousemove(function(e) {
        addCharacter().setPosition(e.pageY, e.pageX).setHSL(width, height).delay(1000).animateToBottom(width, height);
    })
    .click(function(e) {
        $.each({ length : 15 }, function() {
            addCharacter().setPosition(e.pageY, e.pageX).animateToRandomPosition(width, height);
        });
    })
    .keypress(function() {
        addCharacter().setPositionCenter(width, height).animateToRandomPosition(width, height);
    });
});

</script>
<style type="text/css">
html,body {
    background: #fff;
    overflow: hidden;
    height: 100%;
    width: 100%;
}

#canvas div {
    cursor: default;
    font-family: calibri;
    font-weight: normal;
    position: absolute;
    font-family: consolas, "bitstream vera sans mono", monospace;
    line-height:1em;
}
</style>
</head>
<body>
    <div id="canvas"></div>
</body>
</html>
